home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / des_c.exe / lha / ATOB.C < prev    next >
Text File  |  1990-07-14  |  4KB  |  200 lines

  1. /* atob: version 4.0
  2.  * stream filter to change printable ascii from "btoa" back into 8 bit bytes
  3.  * if bad chars, or Csums do not match: exit(1) [and NO output]
  4.  *
  5.  *  Paul Rutter        Joe Orost
  6.  *  philabs!per        petsd!joe
  7.  */
  8.  
  9. /*
  10.  *  DjG - Don Glostein
  11.  *  made changes to code for compiling on non-unix compilers. Main changes
  12.  *  were to the long constants. Originally, not all of them were declared
  13.  *  as such and some compilers promoted in undefined ways. Unlink() function
  14.  *  call moved to end. If done while file was open, on some operating systems
  15.  *  this produced an error at best, and lost clusters at worst.
  16.  *  Introduced code for temp_file to be not in the /tmp directory, for non
  17.  *  unix systems. Introduced SETMODE for those operating systems that default
  18.  *  to new line translation (text mode) for stdin/stdout buffered streams.
  19.  *  NOTE: check the SETMODE and TEMPFILE defines. Make sure they are right for
  20.  *  your machine.
  21.  *  NOTE: if this code is compiled with no defines, then it will default to the
  22.  *  unix operating system version.
  23.  */
  24.  
  25. #include <stdio.h> /* include for all */
  26.  
  27. #ifdef __TURBOC__
  28. #include <fcntl.h>
  29. #include <io.h>
  30. #include <time.h>
  31. #define SETMODE(x) setmode(fileno((x)),O_BINARY)
  32. #define TEMPFILE "atob.%x"
  33. #define    getpid() ((int)time(NULL))
  34. #endif
  35.  
  36. #ifdef MWC_ATARI
  37. #define SETMODE(x) ((x)->_ff &= ~(_FASCII))
  38. #define TEMPFILE "atob.%x"
  39. #endif
  40.  
  41. /* following take care of unix systems */
  42.  
  43. #ifndef TEMPFILE
  44. #define TEMPFILE "/usr/tmp/atob.%x"
  45. #endif
  46.  
  47. #ifndef SETMODE
  48. #define SETMODE(x)
  49. #endif
  50.  
  51. #define reg register
  52.  
  53. #define streq(s0, s1)  strcmp(s0, s1) == 0
  54.  
  55. #define times85(x)    ((((((x<<2)+x)<<2)+x)<<2)+x)
  56.  
  57. long int Ceor = 0L;
  58. long int Csum = 0L;
  59. long int Crot = 0L;
  60. long int word = 0L;
  61.  
  62. int bcount = 0;
  63.  
  64. FILE *tmp_file = (FILE *)NULL;
  65. char tmp_name[100]= {'\0'};
  66.  
  67. fatal()
  68. {
  69.     fprintf(stderr, "bad format or Csum to atob\n");
  70.     if (tmp_file != (FILE *)NULL)
  71.         unlink(tmp_name);
  72.  
  73.     exit(1);
  74. }
  75.  
  76. #define DE(c) ((c) - '!')
  77.  
  78. decode(c)
  79. reg    c;
  80. {
  81.     if (c == 'z') {
  82.         if (bcount != 0) {
  83.             fatal();
  84.         } else {
  85.             byteout(0);
  86.             byteout(0);
  87.             byteout(0);
  88.             byteout(0);
  89.         }
  90.     } else if ((c >= '!') && (c < ('!' + 85))) {
  91.         if (bcount == 0) {
  92.             word = DE(c);
  93.             ++bcount;
  94.         } else if (bcount < 4) {
  95.             word = times85(word);
  96.             word += DE(c);
  97.             ++bcount;
  98.         } else {
  99.             word = times85(word) + DE(c);
  100.             byteout((int)((word >> 24) & 255));
  101.             byteout((int)((word >> 16) & 255));
  102.             byteout((int)((word >> 8) & 255));
  103.             byteout((int)(word & 255));
  104.             word = bcount = 0;
  105.         }
  106.     } else {
  107.         fatal();
  108.     }
  109. }
  110.  
  111. byteout(c)
  112. reg    c;
  113. {
  114.     Ceor ^= c;
  115.     Csum += c;
  116.     Csum += 1;
  117.  
  118.     if ((Crot & 0x80000000)) {
  119.         Crot <<= 1;
  120.         Crot += 1;
  121.     } else {
  122.         Crot <<= 1;
  123.     }
  124.  
  125.     Crot += c;
  126.     putc(c, tmp_file);
  127. }
  128.  
  129. main(argc, argv)
  130. char    **argv;
  131. {
  132.     reg    c;
  133.     reg long i;
  134.     int    ret;
  135.     char    buf[100];
  136.     long    n1, n2, oeor, osum, orot;
  137.  
  138.     if (argc != 1) {
  139.         fprintf(stderr,"bad args to atob\n");
  140.         exit(2);
  141.     }
  142.  
  143.     sprintf(tmp_name, TEMPFILE, getpid());
  144.     tmp_file = fopen(tmp_name, "w+");
  145.  
  146.     if (tmp_file == NULL) {
  147.         perror("couldn't open temp file");
  148.         fatal();
  149.     } else {  /* successful opens, reset mode on text conversion systems */
  150.         SETMODE(stdin);
  151.         SETMODE(tmp_file);
  152.         SETMODE(stdout);
  153.     }
  154.  
  155.     /* search for header line */
  156.  
  157.     for (;;) {
  158.         if (fgets(buf, sizeof buf, stdin) == NULL) {
  159.             fatal();
  160.         }
  161.  
  162.         if (streq(buf, "xbtoa Begin\n")) {
  163.             break;
  164.         }
  165.     }
  166.  
  167.     while ((c = getchar()) != EOF) {
  168.         if (c == '\n') {
  169.             continue;
  170.         } else if (c == 'x') {
  171.             break;
  172.         } else {
  173.             decode(c);
  174.         }
  175.     }
  176.  
  177.     if ((ret = scanf("btoa End N %ld %lx E %lx S %lx R %lx\n",
  178.          &n1, &n2, &oeor, &osum, &orot)) != 5) {
  179.         fprintf(stderr,"\nscanf returned %d", ret);
  180.             fatal();
  181.     }
  182.  
  183.     if ((n1 != n2) || (oeor != Ceor) || (osum != Csum) || (orot != Crot)) {
  184.         fatal();
  185.     } else {
  186.  
  187.         /* copy OK tmp file to stdout */;
  188.  
  189.         fseek(tmp_file, 0L, 0);
  190.  
  191.         for (i = n1; --i >= 0;) {
  192.             putchar(getc(tmp_file));
  193.         }
  194.     }
  195.  
  196.     unlink(tmp_name); /* Make file disappear */
  197.  
  198.     exit(0);
  199. }
  200.